package smooth.core.object.googleMapComponent {
	import com.google.maps.interfaces.IMapType;
	import com.google.maps.interfaces.IOverlay;
	import com.google.maps.LatLng;
	import com.google.maps.LatLngBounds;
	import com.google.maps.MapEvent;
	import com.google.maps.MapType;
	import com.google.maps.controls.MapTypeControl;
	import com.google.maps.controls.PositionControl;
	import com.google.maps.controls.ZoomControl;
	import com.google.maps.overlays.Polyline;
	import com.google.maps.services.ClientGeocoder;
	import com.google.maps.services.GeocodingEvent;
	import com.google.maps.services.GeocodingResponse;
	import com.google.maps.services.Placemark;
	import com.google.maps.overlays.Marker;
	import com.google.maps.overlays.MarkerOptions;
	
	import flash.display.Sprite;
	import flash.events.*;
	import flash.geom.Point;
	
	public class GoogleMapsPureASComponent extends Sprite {
		private static var GOOGLE_MAP_KEY:String = "ABQIAAAALisb9neeZhENyprrzTpbEhT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQNVemsQc-NiaIVnWYCDQdWJJM3gA";
		public static const MAP_STATUS_UNLOADED:int = 0;
		public static const MAP_STATUS_ADDEDTOSTAGE:int = 1;
		public static const MAP_STATUS_READY:int = 2;
		
		public static const HYBRID_MAP_TYPE:int = 0;
		public static const NORMAL_MAP_TYPE:int = 1;
		public static const PHYSICAL_MAP_TYPE:int = 2;
		public static const SATELLITE_MAP_TYPE:int = 3;
		
		private var status:int = MAP_STATUS_UNLOADED;
		private var map:TappableMap;
		private var initialWidth:int;
		private var initialHeight:int;
		private var initialPosX:int;
		private var initialPosY:int;
		private var disableDragging:Boolean;
		private var isFreezed:Boolean;
		private var mapType:int;
		private var initialCenter:LatLng;
		private var initialZoom:Number;
		
		public function GoogleMapsPureASComponent(posX:int, posY:int, sizeX:int, sizeY:int, mapType:int = 3, initialCenter:LatLng = null, initialZoom:Number = 14, disableDragging:Boolean = false, isFreezed:Boolean = false) {
			// Init des attributs de l'objet
			this.initialPosX = posX;
			this.initialPosY = posY;
			this.initialWidth = sizeX;
			this.initialHeight = sizeY;
			this.disableDragging = disableDragging;
			this.isFreezed = isFreezed;
			this.mapType = mapType;
			if (initialCenter == null) {
				this.initialCenter = new LatLng(48.8579,2.2947)
			} else {
				this.initialCenter = initialCenter;
			}
			this.initialZoom = initialZoom;
			// Init des visuels du composant			
			initGraphics();
			// Init des process du composant
			initProcess();
			// Init des events du composant
			initEvents();	
		}
		
		private function initGraphics():void {
		}
		
		private function initProcess():void {
			this.map = new TappableMap(this.disableDragging, this.isFreezed);
			this.map.key = GOOGLE_MAP_KEY;
   			this.map.addEventListener(MapEvent.MAP_READY, onMapReady);
    		this.addChild(map);
		}
		
		private function initEvents():void {
			this.addEventListener(Event.ADDED_TO_STAGE, onAdd);
			this.addEventListener(Event.RESIZE, resizeMap);
		}
		
		private function onAdd(event:Event):void {
			this.status = MAP_STATUS_ADDEDTOSTAGE;
		}
		
		private function onMapReady(event:MapEvent):void {
			this.status = MAP_STATUS_READY;
			// Initialise la taille et la position de la map
			map.setSize(new Point(this.initialWidth, this.initialHeight));
			map.x = this.initialPosX;
			map.y = this.initialPosY;
			// Centre la carte 
			map.setCenter(this.initialCenter, this.initialZoom, traduceFromIntToIMapType(this.mapType));
		    // Initialise les conroles de base
		    map.enableScrollWheelZoom();
		  	// Initialise le type de carte
			this.setMapType(this.mapType);
			// Disable dragging if requested
			if (this.disableDragging) {
				map.disableDragging();
			}
		}
		
		public function setFreezeStatus(isFreezed:Boolean):void {
			this.isFreezed = isFreezed;
			this.map.setFreezeStatus(isFreezed);
		}
		
		public function getMap():TappableMap {
			return this.map;
		}
		
		public function getUniqueId():Number {
			return map.getUniqueId();
		}
		
		public function getStatus():int {
			return this.status;
		}
		
		public function getCenter():LatLng {
			return map.getCenter();
		}
		
		public function getZoom():Number {
			return map.getZoom();
		}
		
		public function getLatLngBounds():LatLngBounds {
			return map.getLatLngBounds();
		}
		
		public function setCenter(latLng:LatLng):void {
			map.setCenter(latLng);
		}
		
		public function setZoom(zoom:Number):void {
			map.setZoom(zoom);
		}
		
		public function setSize(size:Point):void {
			map.setSize(size);
		}
		
		public function zoomIn(latLng:LatLng, centerOnPoint:Boolean=false):void {
			map.zoomIn(latLng, centerOnPoint);
		}
		
		public function zoomOut(latLng:LatLng):void {
			map.zoomOut(latLng);
		}
		
		public function fromViewportToLatLng(point:Point):LatLng {
			return map.fromViewportToLatLng(point,false);
		}
		
		public function fromLatLngToViewport(latLng:LatLng):Point {
			return map.fromLatLngToViewport(latLng,false);
		}
		
		public function globalToLocalMap(point:Point):Point {
			return map.globalToLocal(point);
		}
		
		public function localMapToGlobal(point:Point):Point {
			return map.localToGlobal(point);
		}
		
		public function resizeMap(event:Event):void {
			var center:LatLng = map.getCenter();
			map.setSize(new Point(width, height));
			map.setCenter(center);
			this.dispatchEvent(new MapChangedEvent(map));
		}
		
		public function setMapType(mapType:int):void {
			map.setMapType(this.traduceFromIntToIMapType(mapType));
		}
		
		private function traduceFromIntToIMapType(i:int):IMapType {
			switch (mapType) {
				case HYBRID_MAP_TYPE:
					return MapType.HYBRID_MAP_TYPE;
					break;
				case NORMAL_MAP_TYPE:
					return MapType.NORMAL_MAP_TYPE;
					break;
				case PHYSICAL_MAP_TYPE:
					return MapType.PHYSICAL_MAP_TYPE;
					break;
				case SATELLITE_MAP_TYPE:
					return MapType.SATELLITE_MAP_TYPE;
					break;
			}
		}
		
		public function addOverlay(overlay:IOverlay):void {
			map.addOverlay(overlay);
		}
		
		/*******************************************************
		 * 
		 * GEOCODING
		 * 
		 * *****************************************************/
		public function doGeocodeAddress(address:String):void {
			if (address != "") {
				var geocoder:ClientGeocoder = new ClientGeocoder();
				geocoder.addEventListener(GeocodingEvent.GEOCODING_SUCCESS, onGeocoderSuccess);
				geocoder.addEventListener(GeocodingEvent.GEOCODING_FAILURE, onGeocoderFailure);
				geocoder.geocode(address);
			}
		}
		
		private function onGeocoderSuccess(e:GeocodingEvent):void {
			var response:GeocodingResponse = e.response;
			var placemarks:Array = response.placemarks;
			// START - 20081126 - LSA
			//map.clearOverlays();
			// END - 20081126 - LSA
			for (var i:int = 0; i < placemarks.length; i++ ) {
				var placemark:Placemark = placemarks[i] as Placemark;
				var latLng:LatLng = placemark.point;
				var marker:Marker = new Marker(latLng);
				var markerOptions:MarkerOptions = new MarkerOptions();
				markerOptions.label = e.name;
				markerOptions.hasShadow = true;
				markerOptions.draggable = false;
				this.map.addOverlay(marker);
			}
			if (placemarks.length == 1) {
				this.map.setCenter(placemarks[0].point, 12);
			}
			this.parent.doRefreshAllLayers();
		}
		
		// START - 20081126 - LSA
		public function doAddMarker(lat:Number, lng:Number, label:String=""):void {
			if (lat is Number && lng is Number) {
				var latLng:LatLng = new LatLng(lat, lng);
				var marker:Marker = new Marker(latLng);
				var markerOptions:MarkerOptions = new MarkerOptions();
				markerOptions.label = label;
				markerOptions.hasShadow = true;
				markerOptions.draggable = false;
				this.map.addOverlay(marker);
				this.map.setCenter(latLng, 12);
				this.parent.doRefreshAllLayers();
			}
		}		
		// END - 20081126 - LSA
		
		private function onGeocoderFailure(e:GeocodingEvent):void {
			trace("GoogleMapPureAS::Address not found");
		}
	}
}
